﻿using System;
using System.Collections.Generic;

namespace Sandy.Connections
{
    /// <summary>
    /// A simple static class providing access to pools.
    /// Pool creation is not thread safe for now.
    /// </summary>
    public static class PoolService
    {
        private static Dictionary<string, ConnectionPool> _pools = new Dictionary<string,ConnectionPool>();
        
        private static ConnectionPool CreatePool(string poolName, string host = "localhost", 
                                                int port = 9160, int maxConnections = 50, int lifetime = 30000)
        {
            if (_pools.ContainsKey(poolName)) throw new ArgumentException(string.Format("Pool {0} already exists.", poolName));
            var np = new ConnectionPool(host, port, maxConnections, lifetime);
            _pools.Add(poolName, np);

            return np;
        }

        /// <summary>
        /// Either get an existing pool or create a new one with a given name.
        /// </summary>
        /// <param name="poolName">The name of the requested/new pool.</param>
        /// <param name="host">If a new pool is to be created, the host to use</param>
        /// <param name="port">If a new pool is to be created, the port to use</param>
        /// <param name="maxConnections">If a new pool is to be created, the max number of open connections.</param>
        /// <param name="lifetime">If a new pool is to be created, the maximum lifetime of an idle connection.</param>
        /// <returns>A connection pool</returns>
        public static ConnectionPool FindOrCreate(string poolName, string host = "localhost", 
                                                int port = 9160, int maxConnections = 50, int lifetime = 30000)
        {
            if (_pools.ContainsKey(poolName)) return _pools[poolName];
            return CreatePool(poolName, host, port, maxConnections, lifetime);
        }

        /// <summary>
        /// Returns a new connection to use from a given pool name.
        /// </summary>
        /// <param name="poolName">The pool to use</param>
        /// <returns>A connection from that pool</returns>
        internal static Connection GetConnection(string poolName)
        {
            return _pools[poolName].CreateConnection();
        }

        /// <summary>
        /// Marks the connection as closed in the given pool name.
        /// This is called by SandyClient.Dispose
        /// </summary>
        /// <param name="poolName">The pool name the connection belongs to</param>
        /// <param name="connection">The connection to close</param>
        internal static void CloseConnection(string poolName, Connection connection)
        {
            _pools[poolName].Close(connection);
        }
    }
}
